using ASPApiDemo.Common.Cache;
using ASPApiDemo.Common.Core;
using ASPApiDemo.Common.Option;
using ASPApiDemo.Extension.Redis;
using Microsoft.Extensions.DependencyInjection;
using StackExchange.Redis;

namespace ASPApiDemo.Extension;
// 定义缓存设置静态类，用于在Program.cs中注册缓存服务
public static class CacheSetup
{
    // 统一注册缓存，如果开启了Redis缓存就使用Redis否则使用内存缓存
    public static void AddCacheSetup(this IServiceCollection services)
    {
        var cacheOptions = AppService.GetOptions<RedisOptions>(); // 从配置文件中获取Redis配置选项
        if (cacheOptions.Enable) // 判断是否启用Redis缓存
        {
            // 注册Redis连接多路复用器接口的单例实现
            services.AddSingleton<IConnectionMultiplexer>(sp =>
            {   // 解析Redis连接字符串
                var configuration = ConfigurationOptions.Parse(cacheOptions.ConnectionString, true);
                configuration.ResolveDns = true; // 启用DNS解析，支持域名连接
                return ConnectionMultiplexer.Connect(configuration); // 创建并返回Redis连接
            });
            services.AddSingleton<ConnectionMultiplexer>(p => // 注册ConnectionMultiplexer具体类型的单例，复用已创建的连接实例
                p.GetService<IConnectionMultiplexer>() as ConnectionMultiplexer);
            // 添加Redis分布式缓存服务
            services.AddStackExchangeRedisCache(options =>
            {
                // 设置Redis连接工厂，从服务容器获取已注册的连接实例，设置Redis实例名称
                options.ConnectionMultiplexerFactory = () =>
                    Task.FromResult(AppService.GetService<IConnectionMultiplexer>(false));
                if (!string.IsNullOrEmpty(cacheOptions.InstanceName)) options.InstanceName = cacheOptions.InstanceName;
            });
            services.AddTransient<IRedisBasketRepository, RedisBasketRepository>();// 注册Redis仓储服务，使用瞬时生命周期
        }
        else // Redis未启用时使用内存缓存
        {
            services.AddMemoryCache();// 添加本地内存缓存
            services.AddDistributedMemoryCache();// 添加分布式内存缓存（模拟）
        }
        services.AddSingleton<ICaching, Caching>(); // 注册统一的缓存接口实现，使用单例模式
    }
}